#include "Server.h"

#include <QList>

#define RECIEVED_DATA_MAX_SIZE  4096
#define DATA_CACHE_MAX_SIZE     2048    //接受的最大缓存数据(用来找包头),如果超过则释放掉


_SetGroupExtraDataCallback _ClientsGroupInfo::SetGroupExtraDataCallback = nullptr;
_UnsetGroupExtraDataCallback _ClientsGroupInfo::UnsetGroupExtraDataCallback = nullptr;
_InitGroupExtraDataCallback _ClientsGroupInfo::InitGroupExtraDataCallback = nullptr;
_ReleaseGroupExtraDataCallback _ClientsGroupInfo::ReleaseGroupExtraDataCallback = nullptr;


int _ClientsGroupInfo::SendToGroupAllClients(QByteArray ba, _ClientInfo *pClientInfo)
{
    QList<_ClientInfo*>::const_iterator ii;
    for(ii = m_listClients.constBegin(); ii != m_listClients.constEnd(); ++ii)
    {
        if((*ii) != pClientInfo)
            m_pIOCP->send(*ii,ba);
    }
    qDebug() << "[Group]所有群组发送数据完毕";
    return 0;
}










Server::Server(QObject *parent) :
    QObject(parent)
{
    qRegisterMetaType<_SocketInfo::_SocketContext>("_SocketInfo::_SocketContext");


    m_nRecievedDataMaxSize = RECIEVED_DATA_MAX_SIZE;
    m_nDataCacheMaxSize = DATA_CACHE_MAX_SIZE;
    m_nAcceptedCount = 0;

    m_ConfigFile.readConfigFile(m_vmapConfig);


    m_IOCPModel.InitOnce();

    m_IOCPModel.SetIOCPMessageCallback((void*)Server::Fn_IOCP_Message_Callback,this);
    m_IOCPModel.SetIOCPDbgMessageCallback((void*)Server::Fn_IOCP_MessageDbg_Callback,this);
    m_IOCPModel.SetIOCPAcceptCallback((void*)Server::Fn_IOCP_Accept_Callback,this);
    m_IOCPModel.SetIOCPRecvCallback((void*)Server::Fn_IOCP_Recv_Callback,this);
    m_IOCPModel.SetIOCPSendCallback((void*)Server::Fn_IOCP_Send_Callback,this);
    m_IOCPModel.SetIOCPCloseCallback((void*)Server::Fn_IOCP_Close_Callback,this);


    //m_ThreadPool.start();


    m_txtstreamLog.setDevice(&m_fileLog);

    //OpenLog();




    //!server.listen(QHostAddress::Any,723);
/*
    Debug("");

    //查询所有数据
    QString strSQL = "select * from leamus_ylant_io";
    QSqlQuery sqlQuery(db);
    //sql_query.prepare(strSQL);  //有错误1/2：使用这个且
    if(!sqlQuery.exec(strSQL)) //有错误2/2：忽略参数
    {
        qDebug()<<"!"<<sqlQuery.lastError();
    }
    else
    {
        while(sqlQuery.next())
        {
            int id = sqlQuery.value(0).toInt();
            QString templ_name = sqlQuery.value(1).toString();
            qDebug()<<QString("Id:%1;Templ Name:%2").arg(id).arg(templ_name);
        }
    }
*/
}

Server::~Server()
{
    if(m_fileLog.isOpen())
        m_fileLog.close();

}





//找到房间,没有返回nullptr
_ClientsGroupInfo *Server::GetGroup(QUuid id)
{
    //if(m_mapGroups.contains(id))
    return m_mapGroups.value(id,nullptr);
}

_ClientsGroupInfo* Server::CreateGroup(int playerMaxCount, QString password)
{
    //_ClientsGroupInfo *pGroup = new _ClientsGroupInfo(&this->m_IOCPModel);
    _ClientsGroupInfo *pGroup = m_poolClientsGroupInfo.getOneEmpty();
    pGroup->m_pIOCP = &this->m_IOCPModel;
    pGroup->m_GroupInfo.nClientsMaxCount = playerMaxCount;
    pGroup->m_GroupInfo.strPassword = password;
    m_mapGroups.insert(pGroup->m_uuid, pGroup);

    emit s_Debug(_T("[Server]创建房间:%1").arg(pGroup->m_uuid.toString()));

    return pGroup;
}

int Server::JoinGroup(_ClientInfo* pClientInfo, QUuid id, const QString& password)
{
    _ClientsGroupInfo *pGroup = nullptr;
    if(!id.isNull())
    {
        _ClientsGroupInfo *pGroup = GetGroup(id);
        if(pGroup == nullptr)  //没有这个房间
        {
            emit s_Debug(_T("[Server]加入房间失败"));
            return -10;
        }
    }
    return JoinGroup(pClientInfo, pGroup, password);
}

int Server::JoinGroup(_ClientInfo* pClientInfo, _ClientsGroupInfo *pGroup, const QString& password)
{
    //int ret = 0;
    if(pClientInfo == nullptr)
        return -4;

    //已经加入了房间
    if(pClientInfo->m_pGroup != nullptr)
    {
        return -1;
    }


    //QHash<QUuid,SocketGroup*>::const_iterator ii;
    if(pGroup == nullptr) //随机加入
    {
        QMap<QUuid,_ClientsGroupInfo*>::const_iterator ii;
        for (ii = m_mapGroups.constBegin(); ii != m_mapGroups.constEnd(); ++ii)
        {
            if(!((*ii)->m_flagStatus & _ClientsGroupInfo::Status_Locked)    //没锁
                    && (*ii)->m_listClients.count() < (*ii)->m_GroupInfo.nClientsMaxCount    //没满
                    && (*ii)->m_GroupInfo.strPassword.isEmpty()    //密码空
                    )
            {
                pGroup = (*ii);
                //qDebug()<<"joinGroup"<<id<<pGroup;
                break;
            }
        }
        if(pGroup == nullptr)  //所有房间满
            return -2;
    }
    else    //指定房间
    {
        if(pGroup->m_flagStatus & _ClientsGroupInfo::Status_Locked   //锁
                || pGroup->m_listClients.count() >= pGroup->m_GroupInfo.nClientsMaxCount //满
                || pGroup->m_GroupInfo.strPassword != password)    //密码不对
            return -3;
    }

    pGroup->m_listClients.append(pClientInfo);
    pClientInfo->m_pGroup = pGroup;

    emit s_Debug(_T("[Server]加入房间成功:%1").arg(pGroup->m_uuid.toString()));
    return 0;
}


int Server::ExitGroup(_ClientInfo* pClientInfo)
{
    if(pClientInfo == nullptr)
        return -1;

    //判断原来是否有房间
    if(pClientInfo->m_pGroup == nullptr)
        return -2;

    //如果是群主
    //if(pClientInfo->m_pGroup->m_MasterUser == pClientInfo)
    //{
    //    return CloseGroup(pClientInfo->m_pGroup);
    //}
    //else
    {
        //存在
        if(pClientInfo->m_pGroup->m_listClients.removeOne(pClientInfo))
        {
            _ClientsGroupInfo *pGroup = pClientInfo->m_pGroup;
            pClientInfo->m_pGroup = nullptr;
            emit s_Debug(_T("[Server]退出房间成功:%1").arg(pGroup->m_uuid.toString()));
            return pGroup->m_listClients.length();
        }
        else    //不存在sock
        {
            return -3;
        }
    }
    return -4;
}

int Server::CloseGroup(_ClientsGroupInfo *pGroup)
{
    //已经加入了房间
    if(pGroup == nullptr)
        return -1;

    /*/遍历 群里客户端
    QList<_ClientInfo*>::const_iterator ii;
    for(ii = pGroup->m_listClients.constBegin(); ii != pGroup->m_listClients.constEnd(); ++ii)
    {
        (*ii)->m_pGroup = nullptr;
        //(*ii)->m_flagStatus = serverUserData::Status_Normal;
    }*/

    QList<_ClientInfo*>::const_iterator ii;
    for(ii = pGroup->m_listClients.constBegin(); ii != pGroup->m_listClients.constEnd(); ++ii)
    {
        int ret = ExitGroup(*ii);
        if(ret < 0)
        {
            emit s_Critical(_T("[!Server]关闭房间出错:%1").arg(ret));
            return ret;
        }
        //(*ii)->m_flagStatus = serverUserData::Status_Normal;
    }


    emit s_Debug(_T("[Server]关闭房间:%1").arg(pGroup->m_uuid.toString()));
    m_mapGroups.remove(pGroup->m_uuid);
    m_poolClientsGroupInfo.releaseOneUsing(pGroup);
    //delete pGroup;

    return 0;
}


/*
bool Server::SendAllGroupsInfoToClient(_ClientInfo* pClientInfo)
{

    //遍历 群里客户端
    QList<_ClientInfo*>::const_iterator ii;
    for(ii = m_mapGroups->m_listClients.constBegin(); ii != pGroup->m_listClients.constEnd(); ++ii)
    {

    }
    int j = 0;
    sock->sendData()<<(qint16)GAME_SERVERRESPONSE
                   <<(qint16)GAME_SERVER_GROUP_SENDALLGROUPINFOS;
    //QHash<QUuid,SocketGroup*>::const_iterator ii;
    for (ii = groupList.constBegin(); ii != groupList.constEnd(); ++ii,++j)
    {
        sock->sendData() << (qint16)j << (*ii)->id
                       <<(qint16)((*ii)->socketList.count())
                       <<(qint16)((*ii)->groupBaseinfo.groupMaxCount);
    }
    sock->sendData()<<(qint16)-1;
    sock->send();
    return true;
}

*/




